//
//  Lexer.h
//  LightBasic
//
//  Created by Albert on 21/03/2011.
//  Copyright 2011 LightBasic Development Team. All rights reserved.
//
#pragma once
#include "TokenType.h"
#include "Source.h"

namespace lbc {

    /// The token reference
    class Token;
    
    /**
     * lexer tokenizes the input
     */
    class Lexer : boost::noncopyable
    {
        public:
        
        /// Create new instance of Lexer
        Lexer(const Source & source);
        
        /// construct lexer from a string
        Lexer(const std::string & input);
        
        /// cleanup
        virtual ~Lexer();
        
        /// get next token
        Token * GetNext();
        
        private:
        
        /// init the lexer
        void Init();
        
        /// read next char
        bool ReadChar();
        
        /// Lex identifier (or a keyword)
        Token * LexIdentifier();
        
        /// lex string literal
        Token * LexStringLiteral();
        
        /// lex number literal
        Token * LexNumberLiteral();
        
        /// handle multiline comments
        void LexMultilineComment();
        
        /// make token
        Token * MakeToken(TokenType type, size_t length = 0);
        
        /// Make token
        Token * MakeToken(TokenType type, const std::string & lexeme, size_t length = -1);
        
        // position info
        unsigned int m_line;
        unsigned short m_col;
        
        // start position
        unsigned short m_tokenStart;
        
        // has statement?
        bool m_hasStmt;
        
        /// source pointer if has ownership
        Source * m_ownedSource;
        
        /// the input string
        Source::const_iterator m_input;
    };
    
}